package com.example.testgame;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;

import com.example.testgame.handlers.ScrollHandler;
import com.example.testgame.handlers.ZoomHandler;
import com.example.testgame.sprite.MapBlock;
import com.example.testgame.sprite.MapSprite;
import com.example.testgame.sprite.RoleSprite;
import com.example.testgame.sys.Constant;
import com.example.testgame.sys.Variable;
import com.example.testgame.util.GameHelper;
import com.example.testgame.util.ScreenUtil;

public class GameView extends View {
	
	private int mapWidth;
	private int mapHeight;
	private int mapCols;
	private int mapRows;
	
	private MapSprite mapSprite;
	private List<RoleSprite> roles;
	
	private GestureDetector detector;
	
	private RoleSprite curRoleSprite;

	public GameView(Context context) {
		super(context);
		mapSprite = new MapSprite(context);
		roles = new ArrayList<RoleSprite>();
		RoleSprite lina = new RoleSprite();
		lina.roleAvatar = BitmapFactory.decodeResource(getResources(), R.drawable.role_lina);
		lina.col = 5;
		lina.row = 4;
		roles.add(lina);
		detector = new GestureDetector(getContext(), new MapGestureListener());
		ZoomHandler.addOnZoomChangeListener(new ZoomHandler.OnZoomChangeListener() {
			
			@Override
			public void onZoomChange() {
				invalidate();
			}
		});
		ScrollHandler.addOnScrollChangeListener(new ScrollHandler.OnScrollChangeListener() {
			
			@Override
			public void onScrollChange() {
				invalidate();
			}
		});
		this.setBackgroundColor(Color.DKGRAY);
	}
	
	public void loadMap(MapBlock.BlockType[][] mapData) {
		if(mapData == null || mapData.length == 0 || mapData[0].length == 0) 
			return;
		int row = mapData.length;
		int col = mapData[0].length;
		MapBlock[][] mapBlocks = new MapBlock[row][col];
		for (int i = 0; i < mapData.length; i++) {
			for (int j = 0; j < mapData[i].length; j++) {
				mapBlocks[i][j] = new MapBlock(mapData[i][j]);
			}
		}
		mapSprite.setMapData(mapBlocks);
		Variable.offsetX = (ScreenUtil.screen_width(getContext()) - (col * Constant.BLOCK_WIDTH)) / 2;
		Variable.offsetY = (ScreenUtil.screen_height(getContext()) - (row * Constant.BLOCK_HEIGHT)) / 2;
		
		mapWidth = col * Constant.BLOCK_WIDTH;
		mapHeight = row * Constant.BLOCK_HEIGHT;
		mapCols = col;
		mapRows = row;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		mapSprite.draw(canvas);
		for (RoleSprite roleSprite : roles) {
			roleSprite.draw(canvas);
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		detector.onTouchEvent(event);
		return true;
	}
	
	
	/**
	 * 地图手势监听器
	 * @author zhengjh
	 *
	 */
	private class MapGestureListener extends SimpleOnGestureListener {
		
		@Override
		public boolean onSingleTapConfirmed(MotionEvent e) {
			int x = (int) e.getX();
			int y = (int) e.getY();
			int col = GameHelper.getColByX(x);
			int row = GameHelper.getRowByY(y);
			boolean isClickedRole = false;
			for (RoleSprite roleSprite : roles) {
				if(roleSprite.col == col && roleSprite.row == row) {
					curRoleSprite = roleSprite;
					isClickedRole = true;
					break;
				}
			}
			if(!isClickedRole && curRoleSprite != null) {
				curRoleSprite.col = col;
				curRoleSprite.row = row;
				curRoleSprite = null;
				invalidate();
			}
			return super.onSingleTapConfirmed(e);
		}
		
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			int _mapWidth = (int) (Variable.zoom * mapWidth);
			int minOffsetX;
			int maxOffsetX;
			if(ScreenUtil.screen_width(getContext()) >= _mapWidth) {
				minOffsetX = maxOffsetX = (ScreenUtil.screen_width(getContext()) - _mapWidth) / 2;
			}else {
				minOffsetX = (int) (ScreenUtil.screen_width(getContext()) - _mapWidth);
				maxOffsetX = 0;
			}
			Variable.offsetX -= distanceX;
			if(distanceX > 0) {
				if(Variable.offsetX < minOffsetX) {
					Variable.offsetX = minOffsetX;
				}
			}else {
				if(Variable.offsetX > maxOffsetX) {
					Variable.offsetX = maxOffsetX;
				}
			}

			int _mapHeight = (int) (Variable.zoom * mapHeight);
			int minOffsetY = (int) (ScreenUtil.screen_height(getContext()) - _mapHeight);
			int maxOffsetY = 0;
			if(ScreenUtil.screen_height(getContext()) >= _mapHeight) {
				minOffsetY = maxOffsetY = (ScreenUtil.screen_height(getContext()) - _mapHeight) / 2;
			}else {
				minOffsetY = (int) (ScreenUtil.screen_height(getContext()) - _mapHeight);
				maxOffsetY = 0;
			}
			Variable.offsetY -= distanceY;
			if(distanceY > 0) {
				if(Variable.offsetY < minOffsetY) {
					Variable.offsetY = minOffsetY;
				}
			}else {
				if(Variable.offsetY > maxOffsetY) {
					Variable.offsetY = maxOffsetY;
				}
			}
			invalidate();
			return super.onScroll(e1, e2, distanceX, distanceY);
		}
		
		@Override
		public boolean onDoubleTap(MotionEvent e) {
			float zoom;
			int x = (int) e.getX();
			int y = (int) e.getY();
			if(Variable.zoom >= 2) {
				zoom = 1f;
			}else {
				zoom = 2f;
			}
			ZoomHandler.startZoomTo(zoom, x, y);
			ScrollHandler.startScrollTo(getContext(), x, y);
			return super.onDoubleTap(e);
		}
		
	}

}
